package com.xyz.tasks.bf;

import com.free.exception.SystemException;
import com.free.ext.quartz.TaskContainer;
import com.free.ext.quartz.tasker.RemoteUrlTasker;
import com.free.ext.quartz.tasker.Tasker;
import com.free.utils.DateUtils;
import com.xyz.domain.constants.ConstantsLotteryTaskFormater;
import com.xyz.domain.table.SLottery;
import com.xyz.tasks.tdo.EndTasker;
import com.xyz.tasks.tdo.StartTasker;
import com.xyz.tasks.tdo.TaskTimeObject;
import com.xyz.tasks.tdo.TaskerDealUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class TaskSettingBf {

    @Value("${xyz.lottey.url}")
    private String lotteryUrl;

    @Autowired
    private LotteryProbalityBf lotteryProbalityBf;

    public void mkTaskerInfo(SLottery lottery) throws SystemException {

        String startCode = String.format(ConstantsLotteryTaskFormater.LOTTERY_TASK_CODE_STARTER, lottery.getCode());
        String procCode = String.format(ConstantsLotteryTaskFormater.LOTTERY_TASK_CODE_PROC, lottery.getCode());
        String endCode = String.format(ConstantsLotteryTaskFormater.LOTTERY_TASK_CODE_ENDER, lottery.getCode());
        String remoteUrl = String.format(lotteryUrl, lottery.getCode());


        TaskTimeObject startTimeObj = new TaskTimeObject(lottery.getDayStartTime());
        TaskTimeObject endTimeObj = new TaskTimeObject(lottery.getDayEndTime());
        Date startTime = startTimeObj.getTodayDateInfo();
        Date endTime = endTimeObj.getTodayDateInfo();
        Date now = DateUtils.getCurrentDate();

        StartTasker stTasker = mkStartTasker(startTimeObj, lottery, startCode);
        TaskContainer.instance().add(stTasker);

        EndTasker edTasker = mkEndTasker(endTimeObj, lottery, endCode);
        TaskContainer.instance().add(edTasker);

        boolean isNextDayEnd = false; // 是否是 第一天开始，第二天结束 活动
        if(endTimeObj.getTodayDateInfo().compareTo(startTimeObj.getTodayDateInfo()) <= 0){
            endTime = endTimeObj.getNextDateInfo();
            isNextDayEnd = true;
        }

        lotteryProbalityBf.mkLotteryer(lottery);

        int spanSeconds = TaskerDealUtils.getFixedSpanSeconds(lottery);

        // 当前时间 < 开始时间
        if(now.compareTo(startTime) <= 0){
            if(isNextDayEnd){//第二天结束的活动
                // 当前时间 < 结束时间
                if( now.compareTo(endTime) <= 0 ){
                    long seconds = DateUtils.getDiffTimeOfSeconds(now,endTime) % spanSeconds;
                    long leftSeconds = spanSeconds - seconds;
                    long sleepSeconds = leftSeconds - ConstantsLotteryTaskFormater.LOTTERY_TASK_CACULATE_SECONDS;
                    sleepSeconds = sleepSeconds > 0 ? sleepSeconds : 0;
                    TaskerDealUtils.executAndAddTaskAfterSeconds((int)sleepSeconds, spanSeconds, remoteUrl, mkTasker(procCode, remoteUrl));
                    return;
                }
            }
        }
        else{
            // 活动已经开始一段时间了，不过任务被停止了，恢复时需要重新调用，添加定时任务
            if(now.compareTo(endTime) <= 0){
                long seconds = DateUtils.getDiffTimeOfSeconds(startTime,now) % spanSeconds;
                long leftSeconds = spanSeconds - seconds;
                long sleepSeconds = leftSeconds - ConstantsLotteryTaskFormater.LOTTERY_TASK_CACULATE_SECONDS;
                sleepSeconds = sleepSeconds > 0 ? sleepSeconds : 0;
                TaskerDealUtils.executAndAddTaskAfterSeconds((int)sleepSeconds, spanSeconds, remoteUrl, mkTasker(procCode, remoteUrl));
                return;
            }
        }
        // 当前时间不在任务时间内，直接添加
        TaskerDealUtils.executAndAddTaskAfterSeconds(0, spanSeconds, remoteUrl, mkTasker(procCode, remoteUrl));
    }

    public String mkFixedTimeCron(Integer second, Integer minute, Integer hour) {
        return String.format("%s %s %s * * ? ", second,minute,hour);
    }

    private RemoteUrlTasker mkTasker(String procCode, String remoteUrl){
        RemoteUrlTasker tasker = new RemoteUrlTasker();
        tasker.setGroupNm(ConstantsLotteryTaskFormater.LOTTERY_TASK_GROUP);
        tasker.setTaskNm(procCode);
        tasker.setUrl(remoteUrl);
        return tasker;
    }

    private StartTasker mkStartTasker(TaskTimeObject startTimeObj, SLottery lottery, String startCode){
        StartTasker tasker = new StartTasker();
        tasker.setGroupNm(ConstantsLotteryTaskFormater.LOTTERY_TASK_GROUP);
        tasker.setTaskNm(startCode);
        String cronExpression = mkFixedTimeCron(startTimeObj.getSecond(), startTimeObj.getMinute(), startTimeObj.getHour());
        tasker.setCronExperssion(cronExpression);
        Map<String,Object> map = new HashMap<>();
        map.put(ConstantsLotteryTaskFormater.LOTTERY_TASK_PARAM_OBJ,lottery);
        map.put(ConstantsLotteryTaskFormater.LOTTERY_TASK_PARAM_STARTER, startTimeObj);
        tasker.setParams(map);
        return tasker;
    }

    private EndTasker mkEndTasker(TaskTimeObject endTimeObj, SLottery lottery, String startCode){
        EndTasker tasker = new EndTasker();
        tasker.setGroupNm(ConstantsLotteryTaskFormater.LOTTERY_TASK_GROUP);
        tasker.setTaskNm(startCode);
        String cronExpression = mkFixedTimeCron(endTimeObj.getSecond(), endTimeObj.getMinute(), endTimeObj.getHour());
        tasker.setCronExperssion(cronExpression);
        Map<String,Object> map = new HashMap<>();
        map.put(ConstantsLotteryTaskFormater.LOTTERY_TASK_PARAM_OBJ,lottery);
        map.put(ConstantsLotteryTaskFormater.LOTTERY_TASK_PARAM_ENDER, endTimeObj);
        tasker.setParams(map);
        return tasker;
    }
}
